home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
keyb
/
keybuf21.zip
/
KEYBUF.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-01-20
|
4KB
|
114 lines
BufLen equ 256 ; New keyboard buffer lenght
StdLen equ 32 ; Standard buffer lenght
BVSeg equ 0040h ; BIOS Variables segment
MaxSeg equ 1030h ; Highest suitable segment (read KeyBuf.doc)
DosOwn equ 0008h ; DOS memory block signature
MCBOwn equ 0001h ; Memory Control Bock owner field
MCBNam equ 0008h ; Memory Control Block name field (DOS 4.0+)
; We recalculate the BVS as it was 0000h because it's simples to load it!
; I.e., if Head was 0040:1A, now Head is 0000:041A.
BIOSVar segment byte at 0 ; BVS
org 041Ah
Head dw ? ; Head pointer
Tail dw ? ; Tail pointer
org 0480h
Bot dw ? ; Starting offset of the buffer
Top dw ? ; Offset of the 1st word outside the buffer
BIOSVar ends
KeyBuf segment byte
assume CS:KeyBuf, SS:KeyBuf, DS:KeyBuf, ES:nothing
org 002Ch ; Program environment segment in the PSP
envseg dw ? ; structure.
org 0100h
main: ; Program (.COM) entry point
mov DX,offset greet
mov AH,09h
int 21h ; Greeting message printout
xor AX,AX ; First we see if KeyBuf was already loaded
mov ES,AX ; by calculating the buffer lenght.
mov AX,ES:Top ; The lenght is Top-Bot, of course.
sub AX,ES:Bot ; If we find the usual lenght (32 bytes)
cmp AX,StdLen ; we assume that we really need to run KeyBuf.
jbe first ; We assume otherwise that the buffer is big
mov DX,offset uslss ; enough abd that KeyBuf is useless.
mov AL,01h ; By doing so we detect if KeyBuf has already
jmp exit ; run once.
first:
mov AX,envseg ; First we disallocate the environment
mov ES,AX ; segment. If this segment is big enough
mov AH,49h ; the subsequent allocation call will
int 21h ; get it again. If we want to assemble KeyBuf
xor AX,AX ; as a device driver, we have to remember that
mov envseg,AX ; there's no environment. Never tried.
mov AH,48h ; Now we allocate a 256 bytes (128 2-bytes
mov BX,BufLen/16 ; keystrokes) memory block for our new buffer.
int 21h
jnc allocok ; If allocation fails, we set the allocated
mov AX,65535 ; segment to FFFF.
allocok:
cmp AX,MaxSeg ; Finally we check if the segment in AX is
jb segok ; lower enough in memory to be useful.
mov DX,offset toohi ; Here we use the `trick' with FFFF!
mov AL,02h
jmp exit
segok:
mov DX,AX ; Each memory block allocated has a prepended
dec DX ; memory control clock. It's 16 bytes long and
mov ES,DX ; has a filed for the owner of the block.
mov DI,MCBOwn ; We set the buffer as owned by DOS, so when we
mov DX,DosOwn ; will exit the program, the memory block will
mov ES:[DI],DX ; remain "resident".
mov DI,MCBNam ; Then we copy the string 'KeyBuf' into a field
mov SI,offset greet ; of the memory control block used to store the
mov CX,4 ; the name of the program that allocated it.
rep movsw ; This field has a meaning only for DOS 4.0+ .
mov CL,4 ; With simple calculations we translate
shl AX,CL ; our segment into an offset relatively
sub AX,BVSeg*16 ; to the BVS. (seg*16) = (BVSeg*16)+off
mov DX,AX ; --> off = (seg*16)-(BVSeg*16)
add DX,BufLen
push DS ; We'll use DS to address the BVS to be
xor CX,CX ; as fast as we can while in the disabled
mov DS,CX ; interrupts section below.
assume DS:BIOSVar
cli ; And now ... take the breath!
mov Head,AX ; While juggling with the BVS values
mov Tail,AX ; we have to avoid BIOS to modify those
mov Bot,AX ; values or we could get some incoherency.
mov Top,DX
sti ; Weew! You can breath normally, now!
assume DS:KeyBuf
pop DS
mov DX,offset allok ; Successful message printout and exit
mov AL,CL ; with ERRORLEVEL set to 0.
exit:
mov AH,09h
int 21h
mov AH,4Ch ; MS-DOG exit() service (AL = ERRORLEVEL)
int 21h
greet db 'KeyBuf',0,0, ; This is a dirty trick!
'2.10 (c) 1992-1994 by Shq`n Soft',13,10,'KeyBuf : ','$'
uslss db 'useless',13,10,'$'
toohi db 'all memory below 1030:0 is busy',13,10,'$'
allok db 'successfully installed',13,10,'$'
KeyBuf ends
end main
; That's all, folks!